#! /bin/sh

set -e

#
# Generates gauche-config.c, paths_arch.c and lib/gauche/config.scm
#

# TODO: we have almost exactly the same table in gauche-config.c part
# (cmds[]) and config.scm part (*configurations*).  They should be
# generated from a single source.

host=@host@
xhost=@xhost@
gauche_version=@GAUCHE_VERSION@

case "$xhost" in
  *mingw*|*winnt*)
     # On Windows we can't rely on the paths set by configure.
     # We find the location of the binary and calculate the prefix path
     # from it instead.  The '@' mark will be replaced by the prefix path
     # at runtime.
     prefix=@
     exec_prefix=@
     pathfix='sed -e sx/x\\xg -e sx\\x\\\\xg'
     pathsep=";"
     ;;
  *darwin*-framework)
     # On MacOSX Framework build, we also calculate the paths at runtime,
     # so we can make a framework bundle that can be placed anywhere.
     prefix=@
     exec_prefix=@
     pathfix="cat"
     pathsep=":"
     ;;
  *)
     # Standard configured paths
     prefix=${prefix:-@prefix@}

     exec_prefix=@exec_prefix@
     pathfix="cat"
     pathsep=":"
     ;;
esac

datarootdir=@datarootdir@  # for autoconf 2.60 and later.
garchabi=gauche-@GAUCHE_ABI_VERSION@
garchdir=@libdir@/$garchabi
gdatadir=@datadir@/$garchabi

mandir=`echo @mandir@ | $pathfix`
infodir=`echo @infodir@ | $pathfix`

gauche_incdir=`echo "$garchdir/$gauche_version/include" | $pathfix`
gauche_libdir=`echo "$gdatadir/$gauche_version/lib" | $pathfix`
gauche_aclocaldir=`echo "$gdatadir/$gauche_version/" | $pathfix`
gauche_archdir=`echo "$garchdir/$gauche_version/$host" | $pathfix`
gauche_siteincdir=`echo "$garchdir/site/include" | $pathfix`
gauche_sitelibdir=`echo "$gdatadir/site/lib" | $pathfix`
gauche_sitearchdir=`echo "$garchdir/site/$host" | $pathfix`
gauche_pkgincdir=`echo '${libdir}'"/$garchabi/site/include" | $pathfix`
gauche_pkglibdir=`echo '${datadir}'"/$garchabi/site/lib" | $pathfix`
gauche_pkgarchdir=`echo '${libdir}'"/$garchabi/site/$host" | $pathfix`

gauche_libs="@LIBS@"
gauche_configure_args="@GAUCHE_CONFIGURE_ARGS@"
arch="$host"

local_inc="@LOCAL_INC@"
local_lib="@LOCAL_LIB@"

static_libs="@STATIC_LIBS@"

incdirs=`echo $gauche_incdir | sed s/^-I//`${pathsep}`echo $gauche_siteincdir | sed s/^-I//`
if [ ! -z "@LOCAL_INCDIRS@" ]; then
  incdirs="$incdirs${pathsep}@LOCAL_INCDIRS@"
fi
archdirs=`echo $gauche_archdir | sed s/^-L//`${pathsep}`echo $gauche_sitearchdir | sed s/^-L//`
if [ ! -z "@LOCAL_LIBDIRS@" ]; then
  archdirs="$archdirs${pathsep}@LOCAL_LIBDIRS@"
fi

cc="@CC@"
default_cflags="@DEFAULT_CFLAGS@"

object_suffix="@OBJEXT@"
executable_suffix="@EXEEXT@"
rpath_flag="@RPATH_FLAG@"
shlib_so_suffix="@SHLIB_SO_SUFFIX@"
shlib_so_cflags="@SHLIB_SO_CFLAGS@"
shlib_so_ldflags="@SHLIB_SO_LDFLAGS@"
shlib_so_libs="@SHLIB_LIBS_FOR_EXT@"
shlib_dylib_suffix="@SHLIB_DYLIB_SUFFIX@"
shlib_dylib_ldflags="@SHLIB_DYLIB_LDFLAGS@"
shlib_main_ldflags="@SHLIB_MAIN_LDFLAGS@"
libgauche_so="@LIBGAUCHE_SO@"

#============================================================
# gauche-config.c
#
cat > gauche-config.c.tmp.$$ <<EOF
/* Generated automatically by genconfig.  DO NOT EDIT */

/* The small program gauche-config is installed in the same place
   as gosh, and used to retrieve various configuration information
   later.  It is made a separate program from gosh for quicker
   startup and avoiding complications of dynamic library etc.
   It used to be a shell script, but turned into a C program
   so that it works on the platform that lacks sh. */

#if defined(__MINGW32__) || defined(_MSC_VER)
#define _CRT_SECURE_NO_DEPRECATE 1
#define _CRT_SECURE_NO_WARNINGS  1
#include <winsock2.h>  /* MinGW needs this before windows.h */
#include <windows.h>
#include <shlwapi.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <ctype.h>

static void usage (void) {
  fputs("Usage: gauche-config [option ...]\\n"
        "Multiple options can be given, except --fixup-extension.\\n"
        "\\n"
        "General parameter\\n"
        "  -V   the current gauche version\\n"
        "\\n"
        "Parameters to compile an application using Gauche\\n"
        "  -I   include paths required to compile programs using gauche\\n"
        "       (Note: This doesn't work if Gauche installation directory\\n"
        "       path contains whitespaces.  See --incdirs below.)\\n"
        "  -L   library paths required to link programs using gauche\\n"
        "       (Note: This doesn't work if Gauche installation directory\\n"
        "       path contains whitespaces.  See --archdirs below.)\\n"
        "  -l   libraries required to link programs using gauche\\n"
        "  --cc name of the compiler\\n"
        "  --ac directory that contains Gauche specific autoconf macro\\n"
        "  --reconfigure\\n"
        "       prints the command line used to configure the current\\n"
        "       installation.\\n"
        "  --arch\\n"
        "       prints the architecture signature\\n"
        "  --incdirs, --archdirs\\n"
        "       prints the list of directory names to be looked for include files\\n"
        "       and libraries, respectively.  Each directory name is quoted, as it\\n"
        "       may contain spaces.\\n"
        "\\n"
        "Parameters to install files\\n"
        "  --{sys|site|pkg}libdir\\n"
        "       directories where system|site|package scheme files go\\n"
        "  --{sys|site|pkg}archdir\\n"
        "       directories where system|site|package DSO files go\\n"
        "  --{sys|site|pkg}incdir\\n"
        "       directories where system|site|package header files of extensions go\\n"
        "  --mandir/--infodir\\n"
        "       directories where gauche manpage and info docs are installed\\n"
        "\\n"
        "Parameters to help building extensions\\n"
        "  --object-suffix\\n"
        "       Returns extension of the compiled objects (e.g. 'o')\\n"
        "  --executable-suffix\\n"
        "       Returns extension of the executable (mostly empty, sometimes '.exe')\\n"
        "  --so-suffix\\n"
        "       Suffix for dynamically loadable (dlopen-able) modules\\n"
        "  --so-cflags\\n"
        "       CFLAGS to create dynamically loadable modules\\n"
        "  --so-ldflags\\n"
        "       LDFLAGS to create dynamically loadable modules\\n"
        "  --so-libs\\n"
        "       Required libraries to create dynamically loadable modules\\n"
        "  --dylib-suffix\\n"
        "       Suffix for dynamically linked libraries\\n"
        "  --dylib-ldflags\\n"
        "       LDFLAGS to create dynamically linked libraries\\n"
        "  --rpath-flag\\n"
        "       Compiler flag(s) to embed RPATH\\n"
        "  --static-libs\\n"
        "       Returns a list of libraries required to link Gauche statically.\\n"
        "       Similar to '-l', but this includes the libraries that are used\\n"
        "       for extension modules, and also the static library itself,\\n"
        "       that is -lgauche-static-X.X.\\n"
        ,stderr);
  exit(1);
}

static struct cmd_rec {
    const char *cmd;
    const char *value;
} cmds[] = {
    { "-V", "$gauche_version" },
    { "-I", "-I$gauche_incdir" },
    { "-L", "-L$gauche_archdir $local_lib" },
    { "--ac", "$gauche_aclocaldir" },
    { "-l", "-l$garchabi $gauche_libs" },
    { "--cc", "$cc" },
    { "--reconfigure", "./configure $gauche_configure_args" },

    { "--prefix",      "$prefix" },
    { "--sysincdir",   "$gauche_incdir" },
    { "--siteincdir",  "$gauche_siteincdir" },
    { "--pkgincdir",   "$gauche_pkgincdir" },
    { "--syslibdir",   "$gauche_libdir" },
    { "--sitelibdir",  "$gauche_sitelibdir" },
    { "--pkglibdir",   "$gauche_pkglibdir" },
    { "--sysarchdir",  "$gauche_archdir" },
    { "--sitearchdir", "$gauche_sitearchdir" },
    { "--pkgarchdir",  "$gauche_pkgarchdir" },
    { "--mandir",      "$mandir" },
    { "--infodir",     "$infodir" },
    { "--arch",        "$arch" },
    { "--incdirs",     "$incdirs" },
    { "--archdirs",    "$archdirs" },

    { "--local-incdir", "$local_inc" },
    { "--local-libdir", "$local_lib" },

    { "--default-cflags", "$default_cflags" },

    { "--object-suffix",  "$object_suffix" },
    { "--executable-suffix", "$executable_suffix" },
    { "--rpath-flag",     "$rpath_flag" },
    { "--so-suffix",      "$shlib_so_suffix" },
    { "--so-cflags",      "$shlib_so_cflags" },
    { "--so-ldflags",     "$shlib_so_ldflags" },
    { "--so-libs",        "$shlib_so_libs" },
    { "--dylib-suffix",   "$shlib_dylib_suffix" },
    { "--dylib-ldflags",  "$shlib_dylib_ldflags" },
    { "--libgauche-so",   "$libgauche_so" },
    { "--static-libs",    "$static_libs" },

    { NULL, NULL }
};

#if (defined(__MINGW32__) || defined(_MSC_VER)) && defined(UNICODE)
/* mbs <-> wcs stuff */
#include "win-compat.c"
#define SCM_MBS2WCS(s)   mbs2wcs(s, FALSE, errfn)
#define SCM_WCS2MBS(s)   wcs2mbs(s, FALSE, errfn)
#else  /* !(defined(__MINGW32__) || defined(_MSC_VER)) && defined(UNICODE) */
#define SCM_MBS2WCS(s)  (s)
#define SCM_WCS2MBS(s)  (s)
#endif /* !(defined(__MINGW32__) || defined(_MSC_VER)) && defined(UNICODE) */

static void errfn(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    exit(1);
}

#define PATH_ALLOC(n) malloc(n)
#include "paths.c"

static int process(const char *arg, int check)
{
    struct cmd_rec *cp = cmds;
    while (cp->cmd != NULL) {
        if (strcmp(cp->cmd, arg) == 0) {
            if (!check) printf("%s\\n", replace_install_dir(cp->value, errfn));
            return 1;
        }
        cp++;
    }
    return 0;
}

int main(int argc, char **argv)
{
#if (defined(__MINGW32__) || defined(_MSC_VER)) && defined(UNICODE)
    (void)&mbs2wcs; /* suppress unused function warning */
    (void)&wcs2mbs;
#endif /* (defined(__MINGW32__) || defined(_MSC_VER)) && defined(UNICODE) */

    if (argc < 2) usage();
    if (strcmp(argv[1], "--fixup-extension") == 0) {
        fprintf(stderr, "(fixup-extension is no longer needed.)\n");
    } else {
        char **av;
        for (av = argv+1; *av; av++) {
            if (!process(*av, 1)) usage();
        }
        for (av = argv+1; *av; av++) {
            process(*av, 0);
        }
    }
    return 0;
}

EOF
mv gauche-config.c.tmp.$$ gauche-config.c

#============================================================
# paths_arch.c
#
cat > paths_arch.c.tmp.$$ <<EOF
/* Generated by genconfig.  DO NOT EDIT */
static const char *gauche_arch = "$arch";
static const char *gauche_lib_dir = "$gauche_libdir";
static const char *gauche_arch_dir = "$gauche_archdir";
static const char *gauche_site_lib_dir ="$gauche_sitelibdir";
static const char *gauche_site_arch_dir = "$gauche_sitearchdir";
EOF

mv paths_arch.c.tmp.$$ paths_arch.c

#============================================================
# lib/gauche/config.scm
#
mkdir -p ../lib/gauche
cat > ../lib/gauche/config.scm.tmp.$$ <<EOF
;; Generated by genconfig.  DO NOT EDIT
(define-module gauche.config
  (export gauche-config))
(select-module gauche.config)

(define (gauche-config param)
  (cond [(assoc param *configurations*) 
         => (^p ((with-module gauche.internal %gauche-replace-runtime-directory)
                 (cadr p)))]
        [else (error "unknown configuration parameter name" param)]))

(define *configurations*
  (quote
   (("-V"  "$gauche_version")
    ("-I"  "-I$gauche_incdir")
    ("-L"  "-L$gauche_archdir $local_lib")
    ("--ac"  "$gauche_aclocaldir")
    ("-l"  "-l$garchabi $gauche_libs")
    ("--cc"  "$cc")
    ("--reconfigure"  "./configure $gauche_configure_args")

    ("--prefix"       "$prefix")
    ("--sysincdir"    "$gauche_incdir")
    ("--siteincdir"   "$gauche_siteincdir")
    ("--pkgincdir"    "$gauche_pkgincdir")
    ("--syslibdir"    "$gauche_libdir")
    ("--sitelibdir"   "$gauche_sitelibdir")
    ("--pkglibdir"    "$gauche_pkglibdir")
    ("--sysarchdir"   "$gauche_archdir")
    ("--sitearchdir"  "$gauche_sitearchdir")
    ("--pkgarchdir"   "$gauche_pkgarchdir")
    ("--mandir"       "$mandir")
    ("--infodir"      "$infodir")
    ("--arch"         "$arch")

    ("--incdirs"      "$incdirs")
    ("--archdirs"      "$archdirs")
    ("--local-incdir"  "$local_inc")
    ("--local-libdir"  "$local_lib")

    ("--default-cflags"  "$default_cflags")

    ("--object-suffix"   "$object_suffix")
    ("--executable-suffix"  "$executable_suffix")
    ("--rpath-flag"      "$rpath_flag")
    ("--so-suffix"       "$shlib_so_suffix")
    ("--so-cflags"       "$shlib_so_cflags")
    ("--so-ldflags"      "$shlib_so_ldflags")
    ("--so-libs"         "$shlib_so_libs")
    ("--dylib-suffix"    "$shlib_dylib_suffix")
    ("--dylib-ldflags"   "$shlib_dylib_ldflags")
    ("--libgauche-so"    "$libgauche_so")
    ("--static-libs"     "$static_libs")
    )))

EOF

mv ../lib/gauche/config.scm.tmp.$$ ../lib/gauche/config.scm

# Local variables:
# mode: shell-script
# end:
